package br.com.pentagrama.service.impl;

import java.io.IOException;
import java.io.PrintStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import br.com.pentagrama.service.IClienteConexao;
import br.com.pentagrama.service.ILog;
import br.com.pentagrama.util.ParseUtil;
import br.com.pentagrama.util.Sistema;

public class ClienteConexao implements IClienteConexao {

	private static ClienteConexao instance;
	
	private ILog log;
	
	public static ClienteConexao getInstance() {
		if(instance == null) {
			instance = new ClienteConexao();
		}
		return instance;
	}

	private ClienteConexao() {
		this.log = Sistema.getLog();
	}
	
	public String geraTexto(int size) {
		StringBuilder texto = new StringBuilder();
		for (int i = 0; i < size; i++) {
			texto.append("A");
		}
		return texto.toString();
	}
	
	public double doUpload(int size) {
		// Declaro o socket cliente
		Socket s = null;
		// Declaro a Stream de saida de dados
		PrintStream ps = null;
		try {
			// Cria o socket com o recurso desejado na porta especificada
			s = new Socket("127.0.0.1", 7000);
			// Cria a Stream de saida de dados
			long inicioTransmissao = System.currentTimeMillis();
			ps = new PrintStream(s.getOutputStream());
			// Imprime uma linha para a stream de saída de dados
			ps.println(geraTexto(size));
			long delta = System.currentTimeMillis() - inicioTransmissao;
			double deltaSegundos = delta /1000.0;
			double velocidade = size/deltaSegundos/8.0; 
			return velocidade;
			// Trata possíveis exceções
		} catch (IOException e) {
			log.erro("Erro ao enviar dados pelo socket",e);
		} finally {
			try {
				// Encerra o socket cliente
				s.close();
			} catch (IOException e) {
			}

		}
		return -1;
	}

	public boolean conectarTCP(String ipPorta) {
		Socket s;
		try {
			String ip = ParseUtil.getIP(ipPorta);
			int porta = ParseUtil.getPorta(ipPorta);
			s = new Socket(ip, porta);
			s.setReuseAddress(true);
			s.close();
			log.info("Conex\u00E3o TCP estabelecida com sucesso: " + ipPorta);
			return true;
		} catch (UnknownHostException e) {
			log.alerta("Host não encontrado: " + ipPorta);
		} catch (IOException e) {
			log.alerta("TCP: Conex\u00E3o recusada pelo servidor: " + ipPorta);
		}
		return false;
	}

	public boolean conectarUDP(String ipPorta) {
		try {
			
			String ip = ParseUtil.getIP(ipPorta);
			int porta = ParseUtil.getPorta(ipPorta);
			 DatagramSocket clientSocket = new DatagramSocket();
			 InetAddress IPAddress = InetAddress.getByName(ip);
			 byte[] sendData = new byte[1024];
			 
			 DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, porta);
			 clientSocket.send(sendPacket);
			 clientSocket.close();
			
			 log.info("Realizado acesso via UDP com sucesso: " + ipPorta);
			return true;
		} catch (IOException e) {
			log.alerta("Acesso via UDP recusado: " + ipPorta);
		}
		return false;
	}
}
